package cc.shacocloud.mirage.bean.impl;

import cc.shacocloud.mirage.bean.QualifierHandler;
import cc.shacocloud.mirage.bean.meta.BeanKey;
import cc.shacocloud.mirage.utils.annotation.AnnotatedElementMetadata;
import cc.shacocloud.mirage.utils.annotation.AnnotatedElementUtils;
import cc.shacocloud.mirage.utils.charSequence.StrUtil;
import jakarta.inject.Named;
import jakarta.inject.Qualifier;
import org.jetbrains.annotations.NotNull;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

/**
 * {@link QualifierHandler} 的默认实现
 */
public class DefaultQualifierHandler implements QualifierHandler {
    
    private static final Class<Qualifier> QUALIFIER_ANNOTATION = Qualifier.class;
    private static final Class<Named> NAMED_ANNOTATION = Named.class;
    
    /**
     * 从批注集中获取限定符。限定符是从 {@link Qualifier}继承的任何注释。
     *
     * <p>规则：</p>
     * <ul>
     *   <li>如果未找到 {@link Qualifier} 注解，则返回 {@link BeanKey#ANY_QUALIFIER}</li>
     *   <li>如果找到 {@link Named} 注解，返回值，如果值为空则判断 {@link AnnotatedElement} 为 {@link Method} 或者 {@link Class} 的话，使用驼峰格式的方法名作为名称输出</li>
     *   <li>如果找到任何其他 {@link Qualifier}，则返回注解的类名称</li>
     * </ul>
     */
    @Override
    public String getQualifier(@NotNull AnnotatedElement annotatedElement) {
        String qualifier = null;
        
        AnnotatedElementMetadata annotatedElementMetadata = AnnotatedElementUtils.getAnnotatedMetadata(annotatedElement);
        if (annotatedElementMetadata.isAnnotationPresent(QUALIFIER_ANNOTATION)) {
            
            // 找到 @Named
            if (annotatedElementMetadata.isAnnotationPresent(NAMED_ANNOTATION)) {
                Named named = annotatedElementMetadata.getAnnotation(NAMED_ANNOTATION);
                qualifier = named.value();
                
                // 未定义名称
                if (StrUtil.isBlank(qualifier)) {
                    
                    // 如果是方法则使用方法名称的驼峰规范
                    if (annotatedElement instanceof Method) {
                        qualifier = StrUtil.toLowerFirstCamelCase(((Method) annotatedElement).getName());
                    }
                    // 如果是类则使用类名称的驼峰规范
                    else if (annotatedElement instanceof Class) {
                        qualifier = StrUtil.toLowerFirstCamelCase(((Class<?>) annotatedElement).getSimpleName());
                    }
                }
                
                if (StrUtil.isBlank(qualifier)) {
                    throw new UnsupportedOperationException(annotatedElement + " 上的 @Named 注解未定义名称！");
                }
            }
            // 找到其他这样的的 @Qualifier 返回对应注解的名称
            else {
                for (Annotation annotation : annotatedElementMetadata.getAnnotations()) {
                    if (annotation.annotationType().isAnnotationPresent(QUALIFIER_ANNOTATION)) {
                        qualifier = annotation.annotationType().getName();
                        break;
                    }
                }
            }
        }
        // 未使用限定注解则返回 任意
        else {
            qualifier = BeanKey.ANY_QUALIFIER;
        }
        
        return qualifier;
    }
    
}
